////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __WN_MATH_INTERNAL_X86_CONFIG_H__
#define __WN_MATH_INTERNAL_X86_CONFIG_H__

#ifndef __WN_MATH_CONFIG_H__
    #error "Internal/x86/WNConfig.h should never be included directly."
#elif !defined _WN_X86
    #error "Internal/x86/WNConfig.h has been included on a non x86 platform. Please rectify this."
#elif !defined __WN_MATH_ENABLE_EXTENSIONS
    #error "Internal/x86/WNConfig.h has been included when extensions are disabled. Please rectify this."
#endif

#ifdef _WN_MATH_CONFIG_FORCE_AVX
    #ifdef __WN_AVX_SUPPORTED
        #define __WN_MATH_AVX_FORCED
    #endif

    #ifdef __WN_FMA3_SUPPORTED
        #define __WN_MATH_FMA3_FORCED
    #endif

    #ifdef __WN_FMA4_SUPPORTED
        #define __WN_MATH_FMA4_FORCED
    #endif

    #define _WN_MATH_CONFIG_FORCE_SSE4
#endif

#ifdef _WN_MATH_CONFIG_FORCE_SSE4
    #ifdef __WN_SSE4_1_SUPPORTED
        #define __WN_MATH_SSE4_1_FORCED
    #endif

    #ifdef __WN_SSE4A_SUPPORTED
        #define __WN_MATH_SSE4A_FORCED
    #endif

    #define _WN_MATH_CONFIG_FORCE_SSE3
#endif

#ifdef _WN_MATH_CONFIG_FORCE_SSE3
    #ifdef __WN_SSE3_SUPPORTED
        #define __WN_MATH_SSE3_FORCED
    #endif

    #if defined __WN_SSSE3_SUPPORTED
        #define __WN_MATH_SSSE3_FORCED
    #endif

    #define _WN_MATH_CONFIG_FORCE_SSE2
#endif

#ifdef _WN_MATH_CONFIG_FORCE_SSE2
    #ifdef __WN_SSE2_SUPPORTED
        #define __WN_MATH_SSE2_FORCED
    #endif

    #define _WN_MATH_CONFIG_FORCE_SSE
#endif

#ifdef _WN_MATH_CONFIG_FORCE_SSE
    #ifdef __WN_SSE_SUPPORTED
        #define __WN_MATH_SSE_FORCED
    #endif
#endif

#ifndef __WN_MATH_SSE_FORCED
    #if defined __WN_SSE_SUPPORTED && defined __WN_SSE_AVAILABLE
        #define __WN_MATH_SSE_FORCED
    #endif
#endif

#ifndef __WN_MATH_SSE2_FORCED
    #if defined __WN_SSE2_SUPPORTED && defined __WN_SSE2_AVAILABLE
        #define __WN_MATH_SSE2_FORCED
    #endif
#endif

#ifndef __WN_MATH_SSE3_FORCED
    #if defined __WN_SSE3_SUPPORTED && defined __WN_SSE3_AVAILABLE
        #define __WN_MATH_SSE3_FORCED
    #endif
#endif

#ifndef __WN_MATH_SSSE3_FORCED
    #if defined __WN_SSSE3_SUPPORTED && defined __WN_SSSE3_AVAILABLE
        #define __WN_MATH_SSSE3_FORCED
    #endif
#endif

#ifndef __WN_MATH_SSE4_1_FORCED
    #if defined __WN_SSE4_1_SUPPORTED && defined __WN_SSE4_1_AVAILABLE
        #define __WN_MATH_SSE4_1_FORCED
    #endif
#endif

#ifndef __WN_MATH_AVX_FORCED
    #if defined __WN_AVX_SUPPORTED && defined __WN_AVX_AVAILABLE
        #define __WN_MATH_AVX_FORCED
    #endif
#endif

#if (defined __WN_SSE_SUPPORTED && defined __WN_MATH_ALLOW_RUNTIME) || defined __WN_MATH_SSE_FORCED
    #define __WN_MATH_SSE_ALLOWED
#endif

#if (defined __WN_SSE2_SUPPORTED && defined __WN_MATH_ALLOW_RUNTIME) || defined __WN_MATH_SSE2_FORCED
    #define __WN_MATH_SSE2_ALLOWED
#endif

#if (defined __WN_SSE3_SUPPORTED && defined __WN_MATH_ALLOW_RUNTIME) || defined __WN_MATH_SSE3_FORCED
    #define __WN_MATH_SSE3_ALLOWED
#endif

#if (defined __WN_SSE4_1_SUPPORTED && defined __WN_MATH_ALLOW_RUNTIME) || defined __WN_MATH_SSE4_1_FORCED
    #define __WN_MATH_SSE4_1_ALLOWED
#endif

#if (defined __WN_AVX_SUPPORTED && defined __WN_MATH_ALLOW_RUNTIME) || defined __WN_MATH_AVX_FORCED
    #define __WN_MATH_AVX_ALLOWED
#endif

#ifdef __WN_MATH_SSE_FORCED
    #define __WN_MATH_SSE_AVAILABLE
    #define __WN_MATH_SSE_INLINE WN_FORCE_INLINE
#endif

#ifdef __WN_MATH_SSE2_FORCED
    #define __WN_MATH_SSE2_AVAILABLE
    #define __WN_MATH_SSE2_INLINE WN_FORCE_INLINE
#endif

#ifdef __WN_MATH_SSE3_FORCED
    #define __WN_MATH_SSE3_AVAILABLE
    #define __WN_MATH_SSE3_INLINE WN_FORCE_INLINE
#endif

#ifdef __WN_MATH_AVX_FORCED
    #define __WN_MATH_AVX_AVAILABLE
    #define __WN_MATH_AVX_INLINE WN_FORCE_INLINE
#endif

#ifdef _WN_MATH_CONFIG_DISABLE_SSSE3
    #ifdef __WN_MATH_SSSE3_FORCED
        #undef __WN_MATH_SSSE3_FORCED
    #endif

    #ifdef __WN_MATH_SSSE3_ALLOWED
        #undef __WN_MATH_SSSE3_ALLOWED
    #endif
#endif

#ifdef _WN_MATH_CONFIG_DISABLE_SSE4_1
    #ifdef __WN_MATH_SSE4_1_FORCED
        #undef __WN_MATH_SSE4_1_FORCED
    #endif

    #ifdef __WN_MATH_SSE4_1_ALLOWED
        #undef __WN_MATH_SSE4_1_ALLOWED
    #endif
#endif

#ifdef _WN_MATH_CONFIG_DISABLE_SSE4_2
    #ifdef __WN_MATH_SSE4_2_FORCED
        #undef __WN_MATH_SSE4_2_FORCED
    #endif

    #ifdef __WN_MATH_SSE4_2_ALLOWED
        #undef __WN_MATH_SSE4_2_ALLOWED
    #endif
#endif

#ifdef _WN_MATH_CONFIG_DISABLE_SSE4A
    #ifdef __WN_MATH_SSE4A_FORCED
        #undef __WN_MATH_SSE4A_FORCED
    #endif

    #ifdef __WN_MATH_SSE4A_ALLOWED
        #undef __WN_MATH_SSE4A_ALLOWED
    #endif
#endif

#ifndef __WN_MATH_SSE_INLINE
    #define __WN_MATH_SSE_INLINE static WN_NO_INLINE
#endif

#ifndef __WN_MATH_SSE2_INLINE
    #define __WN_MATH_SSE2_INLINE static WN_NO_INLINE
#endif

#ifndef __WN_MATH_SSE3_INLINE
    #define __WN_MATH_SSE3_INLINE static WN_NO_INLINE
#endif

#ifndef __WN_MATH_AVX_INLINE
    #define __WN_MATH_AVX_INLINE static WN_NO_INLINE
#endif

#endif // __WN_MATH_INTERNAL_X86_CONFIG_H__